package server;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Scanner;
import java.util.TreeSet;


public class Server {
	private ServerSocket ss;
	private TreeSet<String> users = new TreeSet<String>();	//drzewko, na ktorym trzymam nicki userow
	private HashMap<String, ClientResponder> m = new HashMap<String, ClientResponder>(); 	//mapa do trzymania par user - watek piszacy do usera
	
	protected boolean addUser(String name, PrintWriter out) { //zwraca false, jezeli nick jest zajety
		synchronized (users) { 
			System.out.println("Trying to add user: " + name);
			if (users.contains(name)) return false;
			System.out.println("User added: " + name);
			users.add(name);
		}
		synchronized(m) {
			m.put(name, new ClientResponder(out));
			m.get(name).start();
		}
		addToSendForAll(listUsers()); //wysyla do wszystkich liste uzytkownikow
		return true;
	}
	
	protected void removeUser(String name) { 	//usuwa uzytkownika i wysyla wszystkim liste uzytkownikow
		synchronized (users) {
			users.remove(name);
		}
		synchronized(m) {
			m.get(name).die();
			m.remove(name);
		}
		addToSendForAll(listUsers());
	}
	
	protected String listUsers() {
		synchronized (users) {
			String res = "UL ";
			for (String s : users) {
				res += s + " ";
			}
			return res;
		}
	}
	
	protected void addToSendForAll(String text) {	//wysyla wiadomosc do wszystkich
		synchronized(m) {
			for (ClientResponder cR : m.values()) cR.addToSend(text);
		}
	}
	
	protected void addToSendForOne(String text, String name) {	//wysyla wiadomosc prywatna
		synchronized(m) {
			if (!m.containsKey(name)) return;
			m.get(name).addToSend(text);
		}
	}
	
	public Server(int port) {
		try {
			ss = new ServerSocket(port);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void start() {	//tu specjalnie jest start, nie mialem weny na lepsza nazwe
		while(true) {
			try {
				new ClientListener(ss.accept(), this).start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String [] args) {
		System.out.print("Podaj numer portu, na jakim ma dzialac serwer: ");
		new Server(new Scanner(System.in).nextInt()).start();
	}
}